package com.alamiya.common.aop;

import com.alamiya.common.vo.result.ResponseResult;
import com.alibaba.druid.sql.parser.ParserException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.jdbc.UncategorizedSQLException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import javax.validation.ConstraintViolationException;
import java.sql.SQLDataException;
import java.sql.SQLException;
import java.time.format.DateTimeParseException;
import java.util.Objects;

import static com.alamiya.common.constant.ResponseCodeEnum.*;


/**
 * @auther xjl
 * @date 2019/12/3
 * @description 全局异常处理器
 **/
@ControllerAdvice
@Slf4j
@ResponseBody
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ResponseResult handleValidationExceptions(Exception e) {
        log.error("内部错误", e);

        if (e instanceof MethodArgumentNotValidException) {
            return ResponseResult.fail(PARAM_IS_BLANK);
        }

        if (e instanceof ConstraintViolationException) {
            return ResponseResult.fail(PARAM_IS_BLANK);
        }

        if (e instanceof DuplicateKeyException) {
            return ResponseResult.fail(DB_DUPLICATE_KEY);
        }

        if (e instanceof IllegalArgumentException) {
            IllegalArgumentException ex = (IllegalArgumentException) e;
            return ResponseResult.fail(PARAM_ENUM_INVALID);
        }

        if (e instanceof DateTimeParseException) {
            return ResponseResult.fail(PARAM_DATEFORMAT_FAULT);
        }

        if (e instanceof HttpMessageNotReadableException) {
            HttpMessageNotReadableException ex = (HttpMessageNotReadableException) e;
            Throwable rootCause = ex.getRootCause();
            if (!Objects.isNull(rootCause)) {
                if (rootCause instanceof NumberFormatException) {
                    return ResponseResult.fail(PARAM_NUMBERFORMAT_FAULT);
                }
                if (rootCause instanceof IllegalArgumentException) {
                    return ResponseResult.fail(PARAM_IS_BLANK);
                }
            }
            return ResponseResult.fail(PARAM_IS_INVALID);
        }

        if (e instanceof MethodArgumentTypeMismatchException) {
            ResponseResult res = new ResponseResult();
            res.setStatus(FAILURE.getCode());
            MethodArgumentTypeMismatchException matme = (MethodArgumentTypeMismatchException) e;
            res.setMessage(String.format("%s参数类型不正确", matme.getName()));
            return res;
        }

        if (e instanceof SQLDataException || e instanceof SQLException
                || e instanceof DataIntegrityViolationException) {
            return ResponseResult.fail(DB_OPERATE_FAILED);
        }

        if (e instanceof UncategorizedSQLException) {
            UncategorizedSQLException uncategorizedSQLException = (UncategorizedSQLException) e;
            if (uncategorizedSQLException.getCause() instanceof ParserException) {
                return ResponseResult.fail(SQL_PARSE_FAILED);
            }
            return ResponseResult.fail(DB_OPERATE_FAILED);
        }

        return ResponseResult.fail(e.getMessage());
    }

}
